--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit ecbf3e2253fce44940a6dc87b5652e5422e68f5d
Parents : af44499
Author : Ivan <ivan@quad4.io>
Signature : Signature validation error
Date : 2026-04-22T10:52:46-05:00
feat(meshchat): add detection for failed AutoInterfaces and provide user guidance messages
Changes
2 files changed, 69 insertions(+), 4 deletions(-)
Diff
diff --git a/meshchatx/meshchat.py b/meshchatx/meshchat.py
index 706c3225..293779ad 100644
--- a/meshchatx/meshchat.py
+++ b/meshchatx/meshchat.py
@@ -2602,6 +2602,48 @@ class ReticulumMeshChat:
print(f"Failed to write Reticulum config: {e}")
return False
+ def _detect_failed_autointerfaces(self):
+ """Return AutoInterface section names enabled in config but not running.
+ """
+ enabled_names = []
+ try:
+ interfaces = self._get_interfaces_section()
+ except Exception:
+ return []
+
+ if not isinstance(interfaces, dict) or not interfaces:
+ return []
+
+ for name, section in interfaces.items():
+ if not isinstance(section, dict):
+ continue
+ if str(section.get("type", "")).strip() != "AutoInterface":
+ continue
+ enabled_raw = (
+ str(
+ section.get("enabled")
+ or section.get("interface_enabled")
+ or "",
+ )
+ .strip()
+ .lower()
+ )
+ if enabled_raw in ("yes", "true", "1"):
+ enabled_names.append(name)
+
+ if not enabled_names:
+ return []
+
+ try:
+ live = getattr(RNS.Transport, "interfaces", None) or []
+ for iface in live:
+ if iface.__class__.__name__ == "AutoInterface":
+ return []
+ except Exception:
+ return []
+
+ return enabled_names
+
def build_user_guidance_messages(self):
guidance = []
@@ -2618,6 +2660,29 @@ class ReticulumMeshChat:
},
)
+ failed_autointerfaces = self._detect_failed_autointerfaces()
+ if failed_autointerfaces:
+ failed_label = ", ".join(failed_autointerfaces)
+ guidance.append(
+ {
+ "id": "autointerface_bind_failed",
+ "title": "AutoInterface failed to start",
+ "description": (
+ f"AutoInterface '{failed_label}' is enabled in your "
+ "Reticulum config but did not come up at runtime. "
+ "The most common cause is a UDP port collision with "
+ "another local Reticulum application (for example "
+ "Sideband running on the same device on Android). "
+ "Open the interface and set a unique group_id, or "
+ "pick free discovery_port and data_port values, then "
+ "restart Reticulum."
+ ),
+ "action_route": "/interfaces",
+ "action_label": "Open Interfaces",
+ "severity": "warning",
+ },
+ )
+
if (
hasattr(self, "reticulum")
and self.reticulum
@@ -6053,6 +6118,7 @@ class ReticulumMeshChat:
"online": s.get("online"),
"transport_id": transport_id,
"network_id": s.get("network_id"),
+ "autoconnect_source": s.get("autoconnect_source"),
},
)
except Exception as e:
@@ -13567,7 +13633,7 @@ class ReticulumMeshChat:
return identity
except Exception as e:
- print(f"Error recalling identity for {hash_hex}: {e}")
+ print(f"Error recalling identity for {hash_hex}: {type(e).__name__}: {e!r}")
return None
diff --git a/meshchatx/src/version.py b/meshchatx/src/version.py
index d1cb3ff8..b422ff03 100644
--- a/meshchatx/src/version.py
+++ b/meshchatx/src/version.py
@@ -1,6 +1,5 @@
-"""Version string synced from package.json.
-
-Do not edit by hand. Run: pnpm run version:sync.
+"""Version string synced from package.json. Do not edit by hand.
+Run: pnpm run version:sync
"""
__version__ = "4.5.0"
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────